﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;

namespace FinanceSdkDemo
{
    public class ChatDataService
    {

        private long InitSDK()
        {
            long sdk = Finance.NewSdk();

            // 这里填写 企业微信 corpid，secret
            Finance.Init(sdk, "", "");

            return sdk;
        }

        /// <summary>
        /// 获取 聊天信息
        /// </summary>
        public void GetChatDataTest()
        {
            var sdk = InitSDK();
            int seq = 0;
            int limit = 100;//企业微信限制 每次最多请求1000 条
            int timeOut = 500;

            long slice = Finance.NewSlice();

            var ret = Finance.GetChatData(sdk, seq, limit, "", "", timeOut, slice);//获取会话记录数据

            CheckResultInt(ret, nameof(GetChatDataTest));

            //获取返回文本
            var resResultStr = this.GetContentFromSlice(slice);

            // 验证
            var resData = CheckAndGetResultText(resResultStr, "chatdata", nameof(GetChatDataTest));

            JArray jArrayData = JArray.Parse(resData);

            foreach (var item in jArrayData)
            {

                var chatData = this.DecryptChatData(item["encrypt_random_key"]?.ToString(), item["encrypt_chat_msg"]?.ToString());
                // TODO  拿到结果解析
            }
        }


        /// <summary>
        ///  解密 chatdata
        /// </summary>
        /// <param name="encrypt_random_key"></param>
        /// <param name="encrypt_chat_msg"></param>
        /// <returns></returns>
        public string DecryptChatData(string encrypt_random_key, string encrypt_chat_msg)
        {
            var privatekey = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wechat_privateKey.xml"));

            if (string.IsNullOrWhiteSpace(privatekey))
                throw new Exception("privatekey 私钥为空！");

            var random_key = RSAHelper.Decrypt(privatekey, encrypt_random_key);

            if (string.IsNullOrWhiteSpace(random_key))
                throw new Exception("random_key 解密失败！");

            var sliceMsg = Finance.NewSlice();

            var ret = Finance.DecryptData(random_key, encrypt_chat_msg, sliceMsg);

            CheckResultInt(ret, nameof(DecryptChatData));

            //获取返回文本
            var resResultStr = this.GetContentFromSlice(sliceMsg);

            return resResultStr;
        }


        /// <summary>
        /// 获取媒体信息
        /// </summary>
        public void GetMediaData()
        {
            String indexbuf = "";
            long media_data = Finance.NewMediaData();

            long sdk = this.InitSDK();
            List<byte> madiaBytes = new List<byte>();
            while (true)
            {

                string sdkFiled = "CiA2MWZlODNkZjVmM2UxYTI2MjZmZjRkN2MyMzgxZmM5MxI4TkRkZk56ZzRNVE13TVRFME9Ea3pOemd5TUY4eE9UZ3dORGMzTXpNMFh6RTJNREV4TVRrMk1qST0aIDg4NDFmMmY1MzVjZGU0MjQ0N2VlYzc4YjA3NjQzYjU3";

                int ret = Finance.GetMediaData(sdk, indexbuf, sdkFiled, "", "", 50, media_data);

                if (ret != 0)
                {
                    return;
                }
                if (Finance.IsMediaDataFinish(media_data) == 1)
                {


                    var lpByte = Finance.GetData(media_data);

                    int len = Finance.GetDataLen(media_data);
                    var bytes = new Byte[len];

                    System.Runtime.InteropServices.Marshal.Copy(lpByte, bytes, 0, bytes.Length);

                    madiaBytes.AddRange(bytes);

                    File.WriteAllBytes("D:\\123.jpg", madiaBytes.ToArray());

                    Finance.FreeMediaData(media_data);

                    break;
                }
                else
                {

                    var lpByte = Finance.GetData(media_data);

                    int len = Finance.GetDataLen(media_data);
                    var bytes = new Byte[len];

                    System.Runtime.InteropServices.Marshal.Copy(lpByte, bytes, 0, bytes.Length);

                    madiaBytes.AddRange(bytes);


                    indexbuf = Finance.GetOutIndexBuf(media_data);
                   
                }
            }
        }

        /// <summary>
        /// 获取文本
        /// </summary>
        /// <param name="slice"></param>
        /// <returns></returns>
        private string GetContentFromSlice(long slice)
        {
            int len = Finance.GetSliceLen(slice);

            byte[] vbyte = new byte[len];

            var intPtr = Finance.GetContentFromSlice(slice);

            System.Runtime.InteropServices.Marshal.Copy(intPtr, vbyte, 0, vbyte.Length);

            return Encoding.UTF8.GetString(vbyte);
        }

        #region check
        /// <summary>
        /// 验证 sdk 返回的 int信息
        /// </summary>
        private void CheckResultInt(long ret, string methodName = "")
        {
            if (ret == 0) return;

            throw new Exception($"【{methodName}】 验证失败，返回为：{ret}");

        }

        /// <summary>
        ///  验证 sdk 返回的数据信息
        /// </summary>
        /// <param name="result">SDK返回的结果集</param>
        /// <param name="dataColumn">data 列名</param>
        /// <param name="methodName">请求的方法名</param>
        /// <returns></returns>
        private string CheckAndGetResultText(string result, string dataColumn, string methodName = "")
        {
            if (string.IsNullOrWhiteSpace(result))
                throw new Exception($"CheckResultText 【{methodName}】 验证失败，返回结果为空");

            try
            {
                JToken jToken = JToken.Parse(result);

                if (jToken["errcode"].ToString() == "0")
                {
                    return jToken[dataColumn].ToString();
                }

                throw new Exception($"【{methodName}】数据返回失败，errmsg：{jToken["errmsg"]}");

            }
            catch (Exception ex)
            {
                throw new Exception($"【{methodName}】解析失败，错误：{ex.Message}");
            }
        }
        #endregion
    }
}
